home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 2.iso / dist / fw_libmng.idb / usr / freeware / doc / libmng / libmng.txt.z / libmng.txt
Text File  |  2001-10-09  |  41KB  |  1,108 lines

  1. libmng - Multiple-image Network Graphics (MNG) Reference Library 1.0.3
  2.  
  3. DESCRIPTION
  4. The libmng library supports decoding, displaying, encoding, and various
  5. other manipulations of the Multiple-image Network Graphics (MNG) format
  6. image files. It uses the zlib compression library, and optionally the
  7. JPEG library by the Independant JPEG Group (IJG) and/or
  8. lcms (little cms), a color-management library by Marti Maria Saguer.
  9.  
  10.  
  11. I. Introduction
  12.  
  13. This file describes how to use and modify the MNG reference library
  14. (known as libmng) for your own use.  There are seven sections to this
  15. file: introduction, callbacks, housekeeping, reading, displaying, 
  16. writing, and modification and configuration notes for various special
  17. platforms. We assume that libmng is already installed; see the
  18. INSTALL.README file for instructions on how to install libmng.
  19.  
  20. Libmng was written to support and promote the MNG specification.
  21.  
  22. The latest MNG specification (currently 1.0) is available at
  23.   http://www.libpng.org/pub/mng
  24.  
  25. Other information about MNG can be found at the MNG home page at
  26.   http://www.libpng.org/pub/mng
  27.  
  28. The latest version of libmng can be found at its own homepage at
  29.   http://www.libmng.com
  30.  
  31. In most cases the library will not need to be changed.
  32. For standardization purposes the library contains both a Windows DLL
  33. and a makefile for building a shared library (SO). The library is
  34. written in C, but an interface for Borland Delphi is also available.
  35.  
  36. Libmng has been designed to handle multiple sessions at one time,
  37. to be easily modifiable, to be portable to the vast majority of
  38. machines (ANSI, K&R, 32-, and 64-bit) available, and to be easy
  39. to use.
  40.  
  41. Libmng uses zlib for its compression and decompression of MNG files.
  42. Further information about zlib, and the latest version of zlib, can be
  43. found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
  44. The zlib compression utility is a general purpose utility that is
  45. useful for more than MNG/PNG files, and can be used without libmng.
  46. See the documentation delivered with zlib for more details.
  47.  
  48. Libmng optionally uses the JPEG library by the Independant JPEG Group
  49. (IJG). This library is used for the JNG sub-format, which is part of
  50. the MNG specification, and allows for inclusion of JPEG decoded and
  51. thus highly compressed (photographic) images.
  52. Further information about the IJG JPEG library and the latest sources
  53. can be found at <http://www.ijg.org>.
  54.  
  55. Libmng can also optionally use the lcms (little CMS) library by
  56. Marti Maria Saguer. This library provides an excellent color-management
  57. system (CMS), which gives libmng the ability to provide full
  58. color-correction for images with the proper color-information encoded.
  59. Further information and the latest sources can be found at
  60. <http://www.littlecms.com/>.
  61.  
  62. Libmng is thread safe, provided the threads are using different
  63. handles as returned by the initialization call.
  64. Each thread should have its own handle and thus its own image.
  65. Libmng does not protect itself against two threads using the
  66. same instance of a handle.
  67.  
  68. The libmng.h header file is the single reference needed for programming
  69. with libmng:
  70.  
  71. #include <libmng.h>
  72.  
  73.  
  74. II. Callbacks
  75.  
  76. Libmng makes extensive use of callback functions. This is meant to
  77. keep the library as platform-independant and flexible as possible.
  78. Actually, the first call you will make to the library, already contains
  79. three parameters you can use to provide callback entry-points.
  80.  
  81. Most functions must return a mng_bool (boolean). Returning MNG_FALSE
  82. indicates the library the callback failed in some way and the library
  83. will immediately return from whatever it was doing back to the
  84. application. Returning MNG_TRUE indicates there were no problems and
  85. processing can continue.
  86.  
  87. Let's step through each of the possible callbacks. The sections on
  88. reading, displaying and writing will also explain which callbacks are
  89. needed when and where.
  90.  
  91. - mng_ptr mng_memalloc (mng_size_t iLen)
  92.  
  93. A very basic function which the library uses to allocate a memory-block
  94. with the given size. A typical implementation would be:
  95.  
  96.     mng_ptr my_alloc (mng_size_t iLen) {
  97.       return calloc (1, iSize);
  98.     }
  99.  
  100. Note that the library requires you to zero-out the memory-block!!!
  101.  
  102. - void mng_memfree (mng_ptr    pPtr,
  103.                     mng_size_t iLen)
  104.  
  105. Counterpart of the previous function. Typically:
  106.  
  107.     void my_free (mng_ptr pPtr, mng_size_t iLen) {
  108.       free (pPtr);
  109.     }
  110.  
  111. - mng_bool mng_openstream  (mng_handle hHandle)
  112. - mng_bool mng_closestream (mng_handle hHandle)
  113.  
  114. These are called by the library just before it starts to process
  115. (either read or write) a file and just after the processing stops.
  116. This is the recommended place to do I/O initialization & finalization.
  117. Whether you do or not, is up to you. The library does not put any
  118. meaning into the calls. They are simply provided for your convenience.
  119.  
  120. - mng_bool mng_readdata (mng_handle  hHandle, 
  121.                          mng_ptr     pBuf, 
  122.                          mng_uint32  iBuflen, 
  123.                          mng_uint32p pRead)
  124.     
  125. This function is called when the library needs some more input while
  126. reading an image. The reading process supports two modes:
  127. Suspension-mode (SMOD) and non-suspension-mode (NSMOD).
  128. See mng_set_suspensionmode() for a more detailed description.
  129.  
  130. In NSMOD, the library requires you to return exactly the amount of bytes
  131. requested (= iBuflen). Any lesser amount indicates the input file
  132. is exhausted and the library will return a MNG_UNEXPECTEDEOF errorcode.
  133.  
  134. In SMOD, you may return a smaller amount of bytes than requested.
  135. This tells the library it should temporarily wait for more input to
  136. arrive. The lib will return with MNG_NEEDMOREDATA, and will expect a
  137. call to mng_read_resume() or mng_display_resume() next, as soon as
  138. more input-data has arrived.
  139.  
  140. For NSMOD this function could be as simple as:
  141.  
  142.     mng_bool my_read (mng_handle  hHandle,
  143.                       mng_ptr     pBuf, 
  144.                       mng_uint32  iBuflen,
  145.                       mng_uint32p pRead) {
  146.       *pRead = fread (pBuf, 1, iBuflen, myfile);
  147.       return MNG_TRUE;
  148.     }
  149.  
  150. - mng_bool mng_writedata (mng_handle  hHandle,
  151.                           mng_ptr     pBuf, 
  152.                           mng_uint32  iBuflen, 
  153.                           mng_uint32p pWritten)
  154.  
  155. This function is called during the mng_write() function to actually
  156. output data to the file. There is no suspension-mode during write,
  157. so the application must return the exact number of bytes the library
  158. requests to be written.
  159.  
  160. A typical implementation could be:
  161.  
  162.     mng_bool my_write (mng_handle  hHandle,
  163.                        mng_ptr     pBuf, 
  164.                        mng_uint32  iBuflen,
  165.                        mng_uint32p pWritten) {
  166.       *pWritten = fwrite (pBuf, 1, iBuflen, myfile);
  167.       return MNG_TRUE;
  168.     }
  169.  
  170. - mng_bool mng_errorproc (mng_handle  hHandle,
  171.                           mng_int32   iErrorcode,
  172.                           mng_int8    iSeverity,
  173.                           mng_chunkid iChunkname,
  174.                           mng_uint32  iChunkseq,
  175.                           mng_int32   iExtra1,
  176.                           mng_int32   iExtra2,
  177.                           mng_pchar   zErrortext)
  178.  
  179. This function is called whenever an error is detected inside the
  180. library. This may be caused by invalid input, callbacks indicating
  181. failure, or wrongfully calling functions out of place.
  182.  
  183. If you do not provide this callback the library will still return
  184. an errorcode from the called function, and the mng_getlasterror()
  185. function can be used to retrieve the other parameters.
  186.  
  187. This function is currently only provided for convenience, but may
  188. at some point be used to indicate certain errors may be acceptable,
  189. and processing should continue.
  190.  
  191. - mng_bool mng_traceproc (mng_handle hHandle,
  192.                           mng_int32  iFuncnr,
  193.                           mng_int32  iFuncseq,
  194.                           mng_pchar  zFuncname)
  195.  
  196. This function is provided to allow a functional analysis of the
  197. library. This may be useful if you encounter certain errors and
  198. cannot determine what the problem is.
  199.  
  200. Almost all functions inside the library will activate this
  201. callback with an appropriate function-name at the start and end
  202. of the function. Please note that large images may generate an
  203. enormous amount of calls.
  204.  
  205. - mng_bool mng_processheader (mng_handle hHandle,
  206.                               mng_uint32 iWidth,
  207.                               mng_uint32 iHeight)
  208.  
  209. This function is called once the header information of an input-
  210. image has been processed. At this point the image dimensions are
  211. available and also some other properties depending on the type
  212. of the image. Eg. for a MNG the frame-/layercount, playtime &
  213. simplicity fields are known.
  214.  
  215. The primary purpose of this callback is to inform the application
  216. of the size of the image, and for the application to initialize
  217. the drawing canvas to be used by the library. This is also a good
  218. point to set the canvas-style. Eg. mng_set_canvasstyle().
  219.  
  220. - mng_bool mng_processtext (mng_handle hHandle,
  221.                             mng_uint8  iType,
  222.                             mng_pchar  zKeyword,
  223.                             mng_pchar  zText,
  224.                             mng_pchar  zLanguage,
  225.                             mng_pchar  zTranslation)
  226.  
  227. This callback is activated for each textual chunk in the input-
  228. image. These are tEXt, zTXt & iTXt. It may be used to retain
  229. specific comments for presentation to the user.
  230.  
  231. - mng_bool mng_processsave (mng_handle hHandle)
  232. - mng_bool mng_processseek (mng_handle hHandle,
  233.                             mng_pchar  zName)
  234.  
  235. The purpose of these callbacks is to signal the processing of the
  236. SAVE & SEEK chunks in a MNG input-file. This may be used in the
  237. future to specify some special processing. At the moment these
  238. functions are only provided as a signal.
  239.  
  240. - mng_ptr mng_getcanvasline (mng_handle hHandle,
  241.                              mng_uint32 iLinenr)
  242. - mng_ptr mng_getbkgdline   (mng_handle hHandle,
  243.                              mng_uint32 iLinenr)
  244. - mng_ptr mng_getalphaline  (mng_handle hHandle,
  245.                              mng_uint32 iLinenr)
  246.  
  247. These callbacks are used to access the drawing canvas, background
  248. canvas and an optional separate alpha-channel canvas. The latter is
  249. used only with the MNG_CANVAS_RGB8_A8 canvas-style.
  250.  
  251. If the getbkgdline() callback is not supplied the library will
  252. composite full or partially transparent pixels in the image against
  253. a specified background color. See mng_set_bgcolor() for more details.
  254. If a chosen canvas-style includes an alpha-channel, this callback
  255. is very likely not needed.
  256.  
  257. The application is responsible for returning a pointer to a line of
  258. pixels, which should be in the exact format as defined by the call
  259. to mng_set_canvasstyle() and mng_set_bkgdstyle(), without gaps between
  260. the representation of each pixel.
  261.  
  262. - mng_bool mng_refresh (mng_handle hHandle,
  263.                         mng_uint32 iX,
  264.                         mng_uint32 iY,
  265.                         mng_uint32 iWidth,
  266.                         mng_uint32 iHeight)
  267.  
  268. This callback is called when the library has drawn a complete frame
  269. onto the drawing canvas, and it is ready to be displayed.
  270. The application is responsible for transferring the drawing canvas
  271. from memory onto the actual output device.
  272.  
  273. - mng_uint32 mng_gettickcount (mng_handle hHandle)
  274.  
  275. This function should return the number of milliseconds on some internal
  276. clock. The entire animation timing depends heavily on this function,
  277. 1and the number returned should be as accurate as possible.
  278.  
  279. - mng_bool mng_settimer (mng_handle hHandle,
  280.                          mng_uint32 iMsecs)
  281.  
  282. This callback is activated every time the library requires a "pause".
  283. Note that the function itself should NOT execute the wait. It should
  284. simply store the time-field and allow the library to return. Libmng
  285. will return with the MNG_NEEDTIMERWAIT code, indicating the callback
  286. was called and it is now time to execute the pause.
  287.  
  288. After the indicated number of milliseconds have elapsed, the application
  289. should call mng_display_resume(), to resume the animation as planned.
  290.  
  291. This method allows for both a real timer or a simple wait command in the
  292. application. Whichever method you select, both the gettickcount() and
  293. settimer() callbacks are crucial for proper animation timing.
  294.  
  295. - mng_bool mng_processgamma  (mng_handle hHandle,
  296.                               mng_uint32 iGamma)
  297. - mng_bool mng_processchroma (mng_handle hHandle,
  298.                               mng_uint32 iWhitepointx,
  299.                               mng_uint32 iWhitepointy,
  300.                               mng_uint32 iRedx,
  301.                               mng_uint32 iRedy,
  302.                               mng_uint32 iGreenx,
  303.                               mng_uint32 iGreeny,
  304.                               mng_uint32 iBluex,
  305.                               mng_uint32 iBluey)
  306. - mng_bool mng_processsrgb   (mng_handle hHandle,
  307.                               mng_uint8  iRenderingintent)
  308. - mng_bool mng_processiccp   (mng_handle hHandle,
  309.                               mng_uint32 iProfilesize,
  310.                               mng_ptr    pProfile)
  311. - mng_bool mng_processarow   (mng_handle hHandle,
  312.                               mng_uint32 iRowsamples,
  313.                               mng_bool   bIsRGBA16,
  314.                               mng_ptr    pRow)
  315.  
  316. These callbacks are only required when you selected the MNG_APP_CMS
  317. directive during compilation of the library. See the configuration
  318. section for more details.
  319.  
  320. - mng_bool mng_iteratechunk (mng_handle  hHandle,
  321.                              mng_handle  hChunk,
  322.                              mng_chunkid iChunkid,
  323.                              mng_uint32  iChunkseq)
  324.  
  325. This callback is only used for the mng_iterate_chunks() function.
  326. It is called exactly once for each chunk stored.
  327.  
  328.  
  329. III. Housekeeping
  330.  
  331.  
  332. > Memory management
  333.  
  334. The library can use internal memory allocation/deallocation or use
  335. provided callbacks for its memory management. The choice is made at
  336. compilation time. See the section on customization for details.
  337.  
  338. If internal management has been selected, the memory callback functions
  339. need not be supplied. Even if you do supply them they will not be used.
  340. The actual code used is similar to the code discussed in the callback
  341. section:
  342.  
  343.       pPtr = calloc (1, iSize);
  344.  
  345.       free (pPtr);
  346.  
  347. If your compiler does not support these functions, or you wish to monitor
  348. the library's use of memory for certain reasons, you can choose to
  349. compile the library with external memory management. In this case the
  350. memory callback functions MUST be supplied, and should function as if the
  351. above code was used.
  352.  
  353.  
  354. > Initialization
  355.  
  356. The basic initialization of the library is short and swift:
  357.  
  358.     myhandle = mng_initialize (myuserdata, my_alloc, 
  359.                                my_free, MNG_NULL);
  360.     if (myhandle == MNG_NULL)
  361.       /* process error */;
  362.  
  363. The first field is an application-only parameter. It is saved in
  364. libmng's internal structures and available at all times through the
  365. mng_get_userdata() function. This is especially handy in callback functions
  366. if your program may be handling multiple files at the same time.
  367.  
  368. The second and third field supply the library with the memory callback
  369. 1function entry-points. These are described in more detail in the callback
  370. section and the previous paragraph.
  371.  
  372. The fourth and last field may be used to supply the library with the
  373. entry-point of a trace callback function. For regular use you will not
  374. need this!
  375.  
  376. The function returns a handle which will be your ticket to MNG-heaven.
  377. All other functions rely on this handle. It is the single fixed unique
  378. reference-point between your application and the library.
  379.  
  380. You should call the initialization function for each image you wish to
  381. process simultaneously. If you are processing images consecutively, you can
  382. reset the internal status of the library with the mng_reset() function.
  383. This function will clear all internal state variables, free any stored
  384. chunks and/or objects, etc, etc. Your callbacks and other external parameters
  385. will be retained.
  386.  
  387. After you successfully received the handle it is time to set the required
  388. callbacks. The sections on reading, displaying & writing indicate which
  389. callbacks are required and which are optional.
  390. To set the callbacks simply do:
  391.  
  392.     myretcode = mng_setcb_xxxxxx (myhandle, my_xxxxxx);
  393.     if (myretcode != MNG_NOERROR)
  394.       /* process error */;
  395.  
  396. Naturally you'd replace the x's with the name of the callback.
  397.  
  398.  
  399. > Cleanup
  400.  
  401. Once you've gotten hold of that precious mng_handle, you should always,
  402. and I mean always, call the cleanup function when you're done.
  403. Just do:
  404.  
  405.     mng_cleanup (myhandle);
  406.  
  407. And you're done. There shouldn't be an ounce of memory spilled after
  408. that call.
  409.  
  410. Note that if you would like to process multiple files consecutively
  411. you do not need to do mng_cleanup() / mng_initialize() between each file
  412. but simply
  413.  
  414.     myretcode = mng_reset (myhandle);
  415.     if (myretcode != MNG_NOERROR)
  416.       /* process error */;
  417.  
  418. will suffice. Saves some time and effort, that.
  419.  
  420.  
  421. > Error handling
  422.  
  423. From the examples in the previous paragraphs you may have noticed a
  424. meticulous scheme for error handling. And yes, that's exactly what it is.
  425. Practically each call simply returns an errorcode, indicating success,
  426. eg. MNG_NOERROR or failure, anything else but MNG_NEEDMOREDATA and
  427. MNG_NEEDTIMERWAIT. These latter two will be discussed in more detail in
  428. their respective fields of interest: the reading section and displaying
  429. section respectively.
  430.  
  431. It is the application's responsibility to check the returncode after
  432. each call. You can call mng_getlasterror() to receive the details of
  433. the last detected error. This even includes a discriptive error-message
  434. if you enabled that option during compilation of the library.
  435.  
  436. Note that after receiving an error it is still possible to call the
  437. library, but it's also very likely that any following call will fail.
  438. The only functions deemed to work will be mng_reset() and mng_cleanup().
  439. Yes, if you abort your program after an error, you should still call
  440. mng_cleanup().
  441.  
  442.  
  443. IV. Reading
  444.  
  445. Reading a MNG, JNG or PNG is fairly easy. It depends slightly on your
  446. ultimate goal how certain specifics are to be handled, but the basics
  447. are similar in all cases.
  448.  
  449. For the read functioins to work you must have compiled the library with
  450. the MNG_READ_SUPPRT directive. The standard DLL and Shared Library
  451. have this on by default!
  452.  
  453.  
  454. > Setup
  455.  
  456. Naturally you must have initialized the library and be the owner of
  457. a mng_handle. The following callbacks are essential:
  458.  
  459.     mng_openstream, mng_readdata, mng_closestream
  460.  
  461. You may optionally define:
  462.  
  463.     mng_errorproc, mng_traceproc
  464.     mng_processheader, mng_processtext
  465.     mng_processsave, mng_processseek
  466.  
  467. The reading bit will also fail if you are already creating or
  468. displaying a file. Seems a bit obvious, but I thought I'd mention it,
  469. just in case.
  470.  
  471.  
  472. > To suspend or not to suspend
  473.  
  474. There is one choice you need to make before calling the read function.
  475. Are you in need of suspension-mode or not?
  476.  
  477. If you're reading from a disk you most certainly do not need
  478. suspension-mode. Even the oldest and slowest of disks will be fast
  479. enough for straight reading.
  480.  
  481. However, if your input comes from a really slow device, such as a
  482. dialup-line or the likes, you may opt for suspension-mode. This is done
  483. by calling
  484.  
  485.     myretcode = mng_set_suspensionmode (myhandle,
  486.                                         MNG_TRUE);
  487.     if (myretcode != MNG_NOERROR)
  488.       /* process error */;
  489.  
  490. Suspension-mode will force the library to use special buffering on the
  491. input. This allows your application to receive data of arbitrarily length
  492. and return this in the mng_readdata() callback, without disturbing the
  493. chunk processing routines of the library.
  494.  
  495. Suspension-mode does require a little extra care in the main logic of the
  496. 1application. The read function may return with MNG_NEEDMOREDATA when the
  497. mng_readdata() callback returns less data then it needs to process the
  498. next chunk. This indicates the application to wait for more data to arrive
  499. and then resume processing by calling mng_read_resume().
  500.  
  501.  
  502. > The read HLAPI
  503.  
  504. The actual reading is just plain simple. Since all I/O is done
  505. 1outside the library through the callbacks, the library can focus on
  506. its real task. Understanding, checking and labelling the input data!
  507.  
  508. All you really need to do is this:
  509.  
  510.     myretcode = mng_read (myhandle);
  511.     if (myretcode != MNG_NOERROR)
  512.       /* process error */;
  513.  
  514. Of course, if you're on suspension-mode the code is a little more
  515. complicated:
  516.  
  517.     myretcode = mng_read (myhandle);
  518.  
  519.     while (myretcode == MNG_NEEDMOREDATA) {
  520.       /* wait for input-data to arrive */
  521.       myretcode = mng_read_resume (myhandle);
  522.     } 
  523.    
  524.     if (myretcode != MNG_NOERROR)
  525.       /* process error */;
  526.  
  527. This is rather crude and more sophisticated programming methods may
  528. dictate another approach. Whatever method you decide on, it should
  529. act as if the above code was in its place.
  530.  
  531. There is also the mng_readdisplay() function, but this is discussed
  532. in the displaying section. It functions pretty much as the mng_read()
  533. function, but also immediately starts displaying the image.
  534. mng_read_resume() should be replaced by mng_display_resume() in that
  535. case!
  536.  
  537.  
  538. > What happens inside
  539.  
  540. What actually happens inside the library depends on the configuration
  541. options set during the compilation of the library.
  542.  
  543. Basically the library will first read the 8-byte file header, to determine
  544. its validity and the type of image it is about to process. Then it will
  545. repeatedly read a 4-byte chunk-length and then the remainder of the chunk
  546. until it either reaches EOF (indicated by the mng_readdata() callback) or
  547. implicitly decides EOF as it processed the logically last chunk of the
  548. image.
  549.  
  550. Applications that require strict conformity and do not allow superfluous
  551. data after the ending chunk, will need to perform this check in their
  552. mng_closestream() callback.
  553.  
  554. Each chunk is then checked on CRC, after which it is handed over to the
  555. appropriate chunk processing routine. These routines will disect the
  556. chunk, check the validity of its contents, check its position with respect
  557. to other chunks, etc, etc.
  558.  
  559. If everything checks out, the chunk is further processed as follows:
  560.  
  561. If display support has been selected during compilation, certain pre-display
  562. initialization will take place.
  563.  
  564. If chunk-storage support has been selected during compilation, the chunks
  565. data may be stored in a special internal structure and held for future
  566. reference.
  567.  
  568.  
  569. > Storing and accessing chunks
  570.  
  571. One of the compilation options activates support for chunk storage.
  572. This option may be useful if you want to examine an image. The directive
  573. is MNG_STORE_CHUNKS. You must also turn on the MNG_ACCESS_CHUNKS
  574. directive.
  575.  
  576. The actual storage facility can be turned on or off with the
  577. mng_set_storechunks() function. If set to MNG_TRUE, chunks will be
  578. stored as they are read.
  579.  
  580. At any point you can then call the mng_iterate_chunks() function
  581. to iterate through the current list of chunks. This function requires
  582. a callback which is called for each chunk and receives a specific
  583. chunk-handle. This chunk-handle can be used to call the appropriate
  584. mng_getchunk_xxxx() function, to access the chunks properties.
  585.  
  586. A typical implementation may look like this:
  587.  
  588.     mng_bool my_iteratechunk (mng_handle  hHandle,
  589.                               mng_handle  hChunk,
  590.                               mng_chunkid iChunkid,
  591.                               mng_uint32  iChunkseq) {
  592.       switch (iChunkid) {
  593.         case MNG_UINT_MHDR : { /* process MHDR */;
  594.                                break; }
  595.         case MNG_UINT_FRAM : { /* process FRAM */;
  596.                                break; }
  597.  
  598.             ...etc...
  599.  
  600.         case MNG_UINT_HUH  : { /* unknown chunk */; 
  601.                                break; }
  602.         default : { /* duh; forgot one */; }
  603.       }
  604.  
  605.       return MNG_TRUE; /* keep'm coming */
  606.     }
  607.  
  608. To get to the actual chunk fields of lets say a SHOW chunk you would do:
  609.  
  610.     mng_bool isempty;
  611.     mng_uint16 firstid, lastid;
  612.     mng_uint8 showmode;
  613.  
  614.     myretcode mng_getchunk_show (hHandle, hChunk, 
  615.                                  isempty, firstid,
  616.                                  lastid, showmode);
  617.     if (myretcode != MNG_NOERROR)
  618.       /* process error */;
  619.  
  620.  
  621. V. Displaying
  622.  
  623.  
  624. > Setup
  625.  
  626. Assuming you have initialized the library and are the owner of
  627. a mng_handle. The following callbacks are essential:
  628.  
  629.     mng_getcanvasline, mng_refresh
  630.     mng_gettickcount, mng_settimer
  631.  
  632. If you wish to use an application supplied background you must supply:
  633.  
  634.     mng_getbkgdline
  635.  
  636. If you wish to use the MNG_CANVAS_RGB8_A8 canvas style you must supply:
  637.  
  638.     mng_getalphaline
  639.  
  640. You may optionally define:
  641.  
  642.     mng_errorproc, mng_traceproc
  643.     mng_processheader, mng_processtext
  644.     mng_processsave, mng_processseek
  645.  
  646. Note that the mng_processheader() callback is optional but will
  647. be quite significant for proper operation!
  648.  
  649. Displaying an image will fail if you are creating a file or already
  650. displaying one. Yes, you can't display it twice!
  651.  
  652.  
  653. > A word on canvas styles
  654.  
  655. The canvas style describes how your drawing canvas is made up.
  656. You must set this before the library actually starts drawing, so
  657. the mng_processheader() callback is a pretty good place for it.
  658.  
  659. Currently only 8-bit RGB canvas styles are supported, either with
  660. or without an alpha channel.
  661.  
  662. If you like to do alpha composition yourself you can select one of
  663. the canvas styles that include an alpha channel. You can even have
  664. a separate alpha canvas by selecting the MNG_CANVAS_RGB8_A8 style.
  665.  
  666. All styles require a compact model. Eg. MNG_CANVAS_BGR8 requires
  667. your canvas lines in bgrbgrbgr... storage, where each letter
  668. represents an 8-bit value of the corresponding color, and each
  669. threesome makes up the values of one(1) pixel.
  670.  
  671. The library processes a line at a time, so the canvas lines do not
  672. actually need to be consecutive in memory.
  673.  
  674.  
  675. > Alpha composition and application backgrounds
  676.  
  677. All Network Graphics can be partially transparent. This requires
  678. special processing if you need to display an image against some
  679. background. Note that the MNG header (MHDR chunk) contains a
  680. simplicity field indicating whether transparency information in
  681. the file is critical or not. This only applies to embedded images,
  682. which means the full image-frame of the MNG may still contain fully
  683. transparent pixels!
  684.  
  685. Depending on your needs you can supply a single background color,
  686. a background canvas or tell the library to return the alpha-channel
  687. and do alpha composition yourself.
  688.  
  689. This is different from the BACK chunk in a MNG, or the bKGD chunk
  690. in an (embedded) PNG or JNG. The BACK chunk indicates an optional or
  691. mandatory background color and/or image. The bKGD chunk only indicates
  692. an optional background color. These chunks indicate the Authors
  693. preferences. They may be absent in which case you need to supply
  694. some sort of background yourself.
  695.  
  696. > Composing against a background color
  697.  
  698. This is the easiest method. Call the mng_set_bgcolor() function to
  699. set the values of the red, green and blue component of your preferred
  700. background color.
  701.  
  702. Use one of the canvas styles that do not have an alpha-channel, and
  703. which matches your output requirements.
  704.  
  705. > Composing against a background canvas
  706.  
  707. This is somewhat more complicated. You will need to set the
  708. mng_getbkgdline() callback. This will be called whenever the library
  709. needs to compose a partially transparent line.
  710.  
  711. This canvas must hold the background against which the image should
  712. be composed. Its size must match exactly with the image dimensions
  713. and thus the drawing canvas!
  714.  
  715. Use one of the canvas styles that do not have an alpha-channel, and
  716. which matches your output requirements. The canvas style of the
  717. background canvas may even differ from the drawing canvas. The library's
  718. composing will still function properly.
  719.  
  720. > Composing within the application
  721.  
  722. If you have the option in your application to draw a (partially)
  723. transparent canvas to the output device, this option is preferred.
  724.  
  725. Select one of the canvas styles that do have an alpha-channel.
  726. The library will now supply the appropriate alpha information,
  727. allowing the application to compose the image as it sees fit.
  728.  
  729.  
  730. > Color information and CMS
  731.  
  732. Network Graphics may, and usually will, contain color-correction
  733. information. This information is intended to compensate for the
  734. difference in recording and display devices used.
  735.  
  736. This document does not address the specifics of color-management.
  737. See the PNG specification for a more detailed description.
  738.  
  739. > Using little cms by Marti Maria Saguer
  740.  
  741. This is the easiest method, providing you can compile the lcms package.
  742. Select the MNG_FULL_CMS directive during compilation, and sit back and
  743. relax. The library will take care of all color-correction for you.
  744.  
  745. > Using an OS- or application-supplied CMS
  746.  
  747. If you are so lucky to have access to CMS functionality from within
  748. your application, you may instruct the library to leave color-correction
  749. to you.
  750.  
  751. Select the MNG_APP_CMS directive during compilation of the library.
  752. You MUST also set the following callbacks:
  753.  
  754.     mng_processgamma, mng_processchroma,
  755.     mng_processsrgb, mng_processiccp and
  756.     mng_processarow
  757.  
  758. The last callback is called when the library needs you to correct
  759. an arbitrary line of pixels. The other callbacks are called when
  760. the corresponding color-information is encountered in the file.
  761. You must store this information somewhere for use in the
  762. mng_processarow() callback.
  763.  
  764. > Using gamma-only correction
  765.  
  766. This isn't a preferred method, but it's better than no correction
  767. at all. Gamma-only correction will at least compensate for
  768. gamma-differences between the original recorder and your output device.
  769.  
  770. Select the MNG_GAMMA_ONLY directive during compilation
  771. of the library. Your compiler MUST support fp operations.
  772.  
  773. > No color correction
  774.  
  775. Ouch. This is really bad. This is the least preferred method,
  776. but may be necessary if your system cannot use lcms, doesn't
  777. have its own CMS, and does not allow fp operations, ruling out
  778. the gamma-only option.
  779.  
  780. Select the MNG_NO_CMS directive during compilation.
  781. Images will definitely not be displayed as seen by the Author!!!
  782.  
  783.  
  784. > Animations and timing
  785.  
  786. Animations require some form of timing support. The library relies
  787. on two callbacks for this purpose. The mng_gettickcount() and
  788. mng_settimer() callbacks. mng_gettickcount() is used to determine
  789. the passing of time in milliseconds since the beginning of the
  790. animation. This is also used to compensate during suspension-mode
  791. if you are using the mng_readdisplay() function to read & display
  792. the file simultaneously.
  793.  
  794. The callback may return an arbitrary number of milliseconds, but
  795. this number must increase proportionaly between calls. Most modern
  796. systems will have some tickcount() function which derives its
  797. input from an internal clock. The value returned from this function
  798. is more than adequate for libmng.
  799.  
  800. The mng_settimer() callback is called when the library determines
  801. a little "pause" is required before rendering another frame of the
  802. animation. The pause interval is also expressed in milliseconds.
  803. Your application should store this value and return immediately.
  804. The library will then make appropriate arrangements to store its
  805. internal state and returns to your application with the
  806. MNG_NEEDTIMERWAIT code.
  807.  
  808. At that point you should suspend processing and wait the given
  809. interval. Please use your OS features for this. Do not engage some
  810. sort of loop. That is real bad programming practice. Most modern
  811. systems will have some timing functions. A simple wait() function
  812. may suffice, but this may prevent your applications main-task from
  813. running, and possibly prevent the actual update of your output device.
  814.  
  815.  
  816. > The mng_refresh() callback
  817.  
  818. The mng_refresh() callback is called whenever the library has
  819. "finished" drawing a new frame onto your canvas, and just before it
  820. will call the mng_settimer() callback.
  821.  
  822. This allows you to perform some actions necessary to "refresh" the
  823. canvas onto your output device. Please do NOT suspend processing
  824. inside this callback. This must be handled after the mng_settimer()
  825. callback!
  826.  
  827.  
  828. > Displaying while reading
  829.  
  830. This method is preferred if you are reading from a slow input device
  831. (such as a dialup-line) and you wish to start displaying something
  832. as quickly as possible. This functionality is provided mainly for
  833. browser-type applications but may be appropriate for other
  834. applications as well.
  835.  
  836. The method is usually used in unison with the suspension-mode of
  837. the read module. A typical implementation would look like this:
  838.  
  839.     /* initiale library and set required callbacks */
  840.  
  841.     /* activate suspension-mode */
  842.     myretcode = mng_set_suspensionmode (myhandle, 
  843.                                         MNG_TRUE);
  844.     if (myretcode != MNG_NOERROR)
  845.       /* process error */;
  846.  
  847.     myretcode = mng_readdisplay (myhandle);
  848.  
  849.     while ((myretcode == MNG_NEEDMOREDATA) ||
  850.            (myretcode == MNG_NEEDTIMERWAIT)) {
  851.       if (myretcode == MNG_NEEDMOREDATA)
  852.         /* wait for more input-data */;
  853.       else
  854.         /* wait for timer interval */;
  855.  
  856.       myretcode = mng_display_resume (myhandle);
  857.     }
  858.  
  859.     if (myretcode != MNG_NOERROR)
  860.       /* process error */;
  861.  
  862. More advanced programming methods may require a different approach,
  863. but the final result should function as in the code above.
  864.  
  865.  
  866. > Displaying after reading
  867.  
  868. This method is used to display a file that was previously read.
  869. It is primarily meant for viewers with direct file access, such as
  870. 1a local harddisk.
  871.  
  872. Once you have successfully read the file, all you need to do is:
  873.  
  874.     myretcode = mng_display (myhandle);
  875.  
  876.     while (myretcode == MNG_NEEDTIMERWAIT) {
  877.       /* wait for timer interval */;
  878.       myretcode = mng_display_resume (myhandle);
  879.     }
  880.  
  881.     if (myretcode != MNG_NOERROR)
  882.       /* process error */;
  883.  
  884. Again, more advanced programming methods may require a different
  885. approach, but the final result should function as in the code above.
  886.  
  887.  
  888. > Display manipulation
  889.  
  890. Several HLAPI functions are provided to allow a user to manipulate
  891. the normal flow of an animation.
  892.  
  893. - mng_display_freeze (mng_handle hHandle)
  894.  
  895. This will "freeze" the animation in place.
  896.  
  897. - mng_display_resume (mng_handle hHandle)
  898.  
  899. This function can be used to resume a frozen animation, or to force
  900. the library to advance the animation to the next frame.
  901.  
  902. - mng_display_reset (mng_handle hHandle)
  903.  
  904. This function will "reset" the animation into its pristine state.
  905. Calling mng_display_resume() afterwards will restart the animation
  906. from the first frame.
  907.  
  908. - mng_display_golayer    (mng_handle hHandle,
  909.                           mng_uint32 iLayer)
  910. - mng_display_goframe    (mng_handle hHandle,
  911.                           mng_uint32 iFrame)
  912. - mng_display_goplaytime (mng_handle hHandle,
  913.                           mng_uint32 iPlaytime)
  914.  
  915. These three functions can be used to "jump" to a specific layer, frame
  916. or timeslot in the animation. You must "freeze" the animation before
  917. using any of these functions.
  918.  
  919. All above functions may only be called during a timer interval!
  920. It is the applications responsibility to cleanup any resources with
  921. respect to the timer wait.
  922.  
  923.  
  924. VI. Writing
  925.  
  926. The main focus of the library lies in its displaying capabilites.
  927. But it does offer writing support as well.
  928. You can create and write a file, or you can write a file you
  929. have previously read, providing the storage of chunks was enabled
  930. and active.
  931.  
  932. For this to work you must have compiled the library with the
  933. MNG_WRITE_SUPPO1RT and MNG_ACCESS_CHUNKS directives. The standard DLL and
  934. Shared Library have this on by default!
  935.  
  936.  
  937. > Setup
  938.  
  939. As always you must have initialized the library and be the owner of
  940. a mng_handle. The following callbacks are essential:
  941.  
  942.     mng_openstream, mng_writedata, mng_closestream
  943.  
  944. You can optionally define:
  945.  
  946.     mng_errorproc, mng_traceproc
  947.  
  948. The creation and writing functions will fail if you are in the middle
  949. of reading, creating or writing a file.
  950.  
  951.  
  952. > Creating a new file
  953.  
  954. To start a new file the library must be in its initial state.
  955. First you need to tell the library your intentions:
  956.  
  957.     myretcode = mng_create (myhandle);
  958.     if (myretcode != MNG_NOERROR)
  959.       /* process error */;
  960.  
  961. After that you start adding the appropriate chunks:
  962.  
  963.     myretcode = mng_putchunk_mhdr (myhandle, ...);
  964.     if (myretcode != MNG_NOERROR)
  965.       /* process error */;
  966.  
  967. And so on, and so forth. Note that the library will automatically signal
  968. the logical end of the file by the ending chunk. Also the first chunk
  969. will indicate the library the filetype (eg. PNG, JNG or MNG) and force
  970. the proper signature when writing the file.
  971.  
  972. The code above can be simplified, as you can always get the last errorcode
  973. by using the mng_getlasterror() function:
  974.  
  975.     if ( (mng_putchunk_xxxx (myhandle, ...)) or
  976.          (mng_putchunk_xxxx (myhandle, ...)) or
  977.              ...etc...                          )
  978.       /* process error */;
  979.  
  980. Please note that you must have a pretty good understanding of the chunk
  981. specification. Unlike the read functions, there are virtually no checks,
  982. so it is quite possible to write completely wrong files.
  983. It is a good practice to read back your file into the library to verify
  984. its integrity.
  985.  
  986. Once you've got all the chunks added, all you do is:
  987.  
  988.     myretcode mng_write (myhandle);
  989.     if (myretcode != MNG_NOERROR)
  990.       /* process error */;
  991.  
  992. And presto. You're done. The real work is of course carried out in
  993. your callbacks. Note that this is a single operation as opposed to
  994. the read & display functions that may return with MNG_NEEDMOREDATA
  995. and/or MNG_NEEDTIMERWAIT. The write function just does the job, and
  996. only returns after it's finished or if it encounters some
  997. unrecoverable error.
  998.  
  999.  
  1000. > Writing a previously read file
  1001.  
  1002. If you have already successfully read a file, you can use the library to
  1003. write it out as a copy or something. You MUST have compiled the library
  1004. with the MNG_STORE_CHUNKS directive, and you must have done
  1005. mng_set_storechunks (myhandle, MNG_TRUE).
  1006.  
  1007. This doesn't require the MNG_ACCESS_CHUNKS directive, unless you want
  1008. to fiddle with the chunks as well.
  1009.  
  1010. Again all you need to do is:
  1011.  
  1012.     myretcode mng_write (myhandle);
  1013.     if (myretcode != MNG_NOERROR)
  1014.       /* process error */;
  1015.  
  1016.  
  1017. VII. Modifying/Customizing libmng:
  1018.  
  1019. to do
  1020.  
  1021. > Compilation directives
  1022.  
  1023. to do
  1024.  
  1025. > Platform dependant modification
  1026.  
  1027. to do
  1028.  
  1029.  
  1030. References :
  1031.  
  1032. libmng :
  1033.   http://www.libmng.com
  1034.  
  1035. zlib : 
  1036.   http://www.info-zip.org/pub/infozip/zlib/
  1037.  
  1038. IJG JPEG library :
  1039.   http://www.ijg.org
  1040.  
  1041. lcms (little CMS) by Marti Maria Saguer :
  1042.   http://www.littlecms.com/
  1043.  
  1044. MNG specification:
  1045.   http://www.libpng.org/pub/mng
  1046.  
  1047.  
  1048. In the case of any inconsistency between the MNG specification
  1049. and this library, the specification takes precedence.
  1050.  
  1051.  
  1052. The contributing authors would like to thank all those who helped
  1053. with testing, bug fixes, and patience.  This wouldn't have been
  1054. possible without all of you!!!
  1055.  
  1056.  
  1057. COPYRIGHT NOTICE:
  1058.  
  1059. Copyright (c) 2000,2001 Gerard Juyn
  1060.  
  1061. For the purposes of this copyright and license, "Contributing Authors"
  1062. is defined as the following set of individuals:
  1063.  
  1064.    Gerard Juyn
  1065.  
  1066. The MNG Library is supplied "AS IS".  The Contributing Authors
  1067. disclaim all warranties, expressed or implied, including, without
  1068. limitation, the warranties of merchantability and of fitness for any
  1069. purpose.  The Contributing Authors assume no liability for direct,
  1070. indirect, incidental, special, exemplary, or consequential damages,
  1071. which may result from the use of the MNG Library, even if advised of
  1072. the possibility of such damage.
  1073.  
  1074. Permission is hereby granted to use, copy, modify, and distribute this
  1075. source code, or portions hereof, for any purpose, without fee, subject
  1076. to the following restrictions:
  1077.  
  1078. 1. The origin of this source code must not be misrepresented;
  1079. you must not claim that you wrote the original software.
  1080.  
  1081. 2. Altered versions must be plainly marked as such and must not be
  1082. misrepresented as being the original source.
  1083.  
  1084. 3. This Copyright notice may not be removed or altered from any source
  1085. or altered source distribution.
  1086.  
  1087. The Contributing Authors specifically permit, without fee, and
  1088. encourage the use of this source code as a component to supporting
  1089. the MNG and JNG file format in commercial products.  If you use this
  1090. source code in a product, acknowledgment would be highly appreciated.
  1091.  
  1092.  
  1093. Remarks :
  1094.  
  1095. Parts of this software have been adapted from the libpng library.
  1096. Although this library supports all features from the PNG specification
  1097. (as MNG descends from it) it does not require the libpng library.
  1098. It does require the zlib library and optionally the IJG JPEG library,
  1099. and/or the "little-cms" library by Marti Maria Saguer (depending on the
  1100. inclusion of support for JNG and Full-Color-Management respectively.
  1101.  
  1102. This library's function is primarily to read and display MNG
  1103. animations. It is not meant as a full-featured image-editing
  1104. component! It does however offer creation and editing functionality
  1105. at the chunk level. (future modifications may include some more
  1106. support for creation and or editing)
  1107.  
  1108.